import ObsClient from "esdk-obs-browserjs"
import { generateFileNameWithUUID } from '#/utils/generateUUID'
import { router } from '#/router'
import { useObsStore } from '#/store/obs'
import { useUserStore } from '@vben/stores';

export type obsDataType = {
  [key: string]: any,
  access_key_id?: string,
  secret_access_key?: string,
  server?: string,
  Bucket?: string,//桶的名称
  Key: string,//path
  ResponseContentType?: string,
  SaveByType?: string,
  isUUID?: boolean
}

export type uploadType = {
  [key: string]: any,
  server?: string,
  Bucket?: string,//桶的名称
  Key: string,//path
  isUUID?: boolean
}

export interface ChunkInfo {
  chunk: Blob
  partNumber: number // OBS要求的分段号（1-10000）
  fileName: string
  totalChunks: number
}

export interface PartInfo {
  PartNumber: number
  ETag: string
}

// https://dev-edu-obs.obs.cn-north-4.myhuaweicloud.com/edu/screenshot-20250510-205021.png
//https://dev-edu-obs.obs.cn-north-4.myhuaweicloud.com/edu/obs-sdk-browserjs-devg.pdf

// const Bucket = 'dev-edu-obs'
const Bucket = import.meta.env.VITE_OBS_BUCKET
const AK = import.meta.env.VITE_ACCESS_KEY_ID
const SK = import.meta.env.VITE_SECRET_ACCESS_KEY
const SERVER = import.meta.env.VITE_SERVER
//实例化OBS
const obsIns = (d: {
  [key: string]: any,
  access_key_id?: string,
  secret_access_key?: string,
  server?: string,
}) => {
  const obsStore = useObsStore()
  const obs = obsStore.getObs('obs')
  !d.server && (d.server = SERVER)
  if (!obs) {
    obsStore.setObs('obs', new ObsClient({
      access_key_id: AK,
      secret_access_key: SK,
      ...d,
    }))
  }
  return obsStore.getObs('obs')
}

const getKey = (key: string) => {
  const userStore = useUserStore()
  // 使用 router.currentRoute.value 获取当前路由信息
  const currentRoute = router.currentRoute.value
  const firstPath = currentRoute.path.split('/')[1] ?? import.meta.env.VITE_OBS_KEY
  let Key = `${generateFileNameWithUUID(key)}`
  //user
  //newkey=`${user}/${Key}`
  // 检查Key是否已经包含firstPath，如果没有则拼接
  if (!Key.includes(firstPath)) {
    Key = `${firstPath}/${Key}`
  }
  if(userStore.tenant){
    Key= `${userStore.tenant.tenantName}_${userStore.tenant.tenantId}/${Key}`
  }
  return Key
}

//下载
const obsDownload = (data: obsDataType, callback?: Function) => {
  const { server, Key, ResponseContentType, SaveByType, ...other } = data;
  const obs = obsIns({ server })
  obs.getObject({
    Bucket,
    Key,
    // ResponseContentType: ResponseContentType || 'application/json;charset=UTF-8',
    SaveByType: SaveByType || 'arraybuffer',
    // SaveByType: SaveByType || 'blob' ,
    ...other
  }, callback)
}

//上传 域名加文件名
const obsUpload = (data: uploadType, callback?: Function) => {
  let { server, Key, isUUID = true, ...other } = data;

  if (isUUID) {
    Key = getKey(Key)
  }
  const ob = obsIns({ server })
  ob.putObject({
    Bucket,
    Key,
    ...other
  }, (...args: any[]) => {
    callback?.(...args, Key)
  })
}

//删除文件
const obsDelete = (data: { server?: string, Key: string }, callback?: Function) => {
  const { server, Key, ...other } = data;
  const obs = obsIns({ server })
  obs.deleteObject({
    Bucket,
    Key,
    ...other
  }, callback)
}


//导出
const downloadFile = (obs: obsDataType, blobConfig?: { [key: string]: any }, type?: string) => {
  if (!obs.Key) return
  obsDownload({
    ...obs,
  }, (err: any, result: any) => {
    if (err) {
      console.error('获取失败:', err);
      return;
    }
    // 创建Blob对象并触发下载
    const blob = new Blob(
      [result.InterfaceResult.Content],
      { ...blobConfig }
    );
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = obs.Key.split('/').pop?.() ?? '';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(link.href);
  })
}

// 初始化分段上传任务
function initiateMultipartUpload(data: { server?: string, Key: string }): Promise<string> {
  const { server, Key, ...other } = data;
  return new Promise((resolve, reject) => {
    const obsClient = obsIns({ server })

    obsClient.initiateMultipartUpload({
      Bucket,
      Key,
      ContentType: 'video/*',
      Metadata: {
        'upload-type': 'chunked-video',
        'original-name': Key.split('/').pop()
      },
      ...other
    }, (err: any, result: any) => {
      if (err) {
        console.error('初始化分段上传失败:', err)
        reject(err)
      } else if (result.CommonMsg.Status < 300 && result.InterfaceResult) {
        console.log('初始化分段上传成功，UploadId:', result.InterfaceResult.UploadId)
        resolve(result.InterfaceResult.UploadId)
      } else {
        reject(new Error('初始化分段上传失败'))
      }
    })
  })
}

// 上传单个分片
function uploadPart(
  data: { server?: string, Key: string, UploadId: string, chunkInfo: ChunkInfo }
): Promise<PartInfo> {
  const { server, Key, UploadId, chunkInfo, ...other } = data;
  return new Promise((resolve, reject) => {
    const obsClient = obsIns({ server })

    obsClient.uploadPart({
      Bucket,
      Key,
      PartNumber: chunkInfo.partNumber,
      UploadId,
      SourceFile: chunkInfo.chunk,
      ...other
    }, (err: any, result: any) => {
      if (err) {
        console.error(`上传分片${chunkInfo.partNumber}失败:`, err)
        reject(err)
      } else if (result.CommonMsg.Status < 300 && result.InterfaceResult) {
        console.log(`分片${chunkInfo.partNumber}上传成功，ETag:`, result.InterfaceResult.ETag)
        resolve({
          PartNumber: chunkInfo.partNumber,
          ETag: result.InterfaceResult.ETag
        })
      } else {
        reject(new Error(`上传分片${chunkInfo.partNumber}失败`))
      }
    })
  })
}

// 完成分段上传（合并分片）
function completeMultipartUpload(
  data: { server?: string, Key: string, UploadId: string, parts: PartInfo[] }
): Promise<string> {
  const { server, Key, UploadId, parts, ...other } = data;
  return new Promise((resolve, reject) => {
    const obsClient = obsIns({ server })

    // 按分段号排序
    const sortedParts = parts.sort((a, b) => a.PartNumber - b.PartNumber)

    obsClient.completeMultipartUpload({
      Bucket,
      Key,
      UploadId,
      Parts: sortedParts,
      ...other
    }, (err: any, result: any) => {
      if (err) {
        console.error('完成分段上传失败:', err)
        reject(err)
      } else if (result.CommonMsg.Status < 300) {
        console.log('分段上传完成成功')
        resolve(Key)
      } else {
        reject(new Error('完成分段上传失败'))
      }
    })
  })
}

// 取消分段上传
function abortMultipartUpload(
  data: { server?: string, Key: string, UploadId: string }
): Promise<void> {
  const { server, Key, UploadId, ...other } = data;
  return new Promise((resolve, reject) => {
    const obsClient = obsIns({ server })

    obsClient.abortMultipartUpload({
      Bucket,
      Key,
      UploadId,
      ...other
    }, (err: any, result: any) => {
      if (err) {
        console.error('取消分段上传失败:', err)
        reject(err)
      } else {
        console.log('分段上传已取消')
        resolve()
      }
    })
  })
}


export {
  downloadFile,
  obsDownload,
  obsUpload,
  obsDelete,
  obsIns,
  initiateMultipartUpload,
  uploadPart,
  completeMultipartUpload,
  abortMultipartUpload,
  getKey
}

